// EditItemPanel.cpp : implementation file
//

#include "stdafx.h"
#include "dq9.h"
#include "EditItemPanel.h"
#include "ItemCategory.h"
#include "EventCodes.h"
#include "EventManagerSngl.h"
#include "PropertiesDlg.h"
#include "PropertyCtrl.h"
#include "Item.h"
#include <utility/Config.h>

#ifdef WIN32
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif //_DEBUG
#endif //WIND32

// EditItemPanel dialog

#define LAYOUT(name) \
	this->LayoutItem(name, _T(#name))

namespace serika
{
	namespace dq
	{
		int EditItemPanel::CTRL_BASE_Y = 100;
		int EditItemPanel::CTRL_HEIGHT = 25;

		IMPLEMENT_DYNAMIC(EditItemPanel, CDialog)

		EditItemPanel::EditItemPanel(CWnd* pParent /*=NULL*/)
			: CDialog(EditItemPanel::IDD, pParent)
			, mItem(0)
			, mConfig(0)
		{
		}

		EditItemPanel::~EditItemPanel()
		{
		}

		void EditItemPanel::Handle(const ut::Event& e)
		{
			switch (e.GetType())
			{
			case ut::EventType::Logic:
				this->OnLogicEvent(e);
				break;

			case ut::EventType::UI:
				this->OnUiEvent(e);
				break;
			}
		}

		void EditItemPanel::OnLogicEvent(const ut::Event& e)
		{
			switch (e.GetCode())
			{
			case LEC::ItemCategories:
				this->OnItemCategories(e);
				break;
			}
		}

		void EditItemPanel::OnUiEvent(const ut::Event& e)
		{
			switch (e.GetCode())
			{
			case UEC::ItemProperty:
				this->OnUiItemProperty(e);
				break;
			}
		}

		void EditItemPanel::OnItemCategories(const ut::Event& e)
		{
			const ItemCategories& categories = *e.GetUserData<ItemCategories>();
			mCategories = categories;
			int index = 0;
			mBox.ResetContent();
			for (ItemCategories::const_iterator itr = categories.begin();
				itr != categories.end(); ++itr)
			{
				ItemCategory* category = *itr;
				mBox.InsertString(index++, category->GetName().c_str());
			}
			mBox.SetCurSel(0);
		}

		void EditItemPanel::OnUiItemProperty(const ut::Event& e)
		{
			Property* p = e.GetUserData<Property>();
			mItem->AddProperty(p);
			PropertyCtrl* ctrl = new PropertyCtrl(this, p);
			ctrl->Create(CTRL_HEIGHT, this);
			int index = mCtrls.size();
			mCtrls.push_back(ctrl);
			this->MoveCtrl(index, ctrl);
		}

		void EditItemPanel::DoDataExchange(CDataExchange* pDX)
		{
			CDialog::DoDataExchange(pDX);
		}

		BOOL EditItemPanel::OnInitDialog()
		{
			CDialog::OnInitDialog();

			mBox.SubclassDlgItem(IDC_CATEGORY_COMBO, this);

			this->Layout();

#ifdef LAYOUT_UI
			mLayoutUITimer = this->SetTimer(0, 1000, 0);
#endif
			return TRUE;
		}

		BEGIN_MESSAGE_MAP(EditItemPanel, CDialog)
			ON_WM_DESTROY()
#ifdef LAYOUT_UI
			ON_WM_TIMER()
#endif
		END_MESSAGE_MAP()

		// EditItemPanel message handlers
		void EditItemPanel::OnDestroy()
		{
			this->ClearCtrl();

			EventManager::DetachLogicEventHandler(this);
			EventManager::DetachUiEventHandler(this);
			PropertiesDlg::Hide();
		}

#ifdef LAYOUT_UI
		void EditItemPanel::OnTimer(UINT_PTR nIDEvent)
		{
			this->Layout();
		}
#endif

		void EditItemPanel::OnActivate()
		{
			EventManager::AttachLogicEventHandler(this);
			EventManager::AttachUiEventHandler(this);
			PropertiesDlg::Show(this);

			//ut::Event* e = ut::Event::NewEvent(ut::EventType::UI, UEC::RequestNewItem);
			//e->SetSource(mItemType);
			//EventManager::SendEvent(e);
			//e = ut::Event::NewEvent(ut::EventType::UI, UEC::RequestPropertyTemplates);
			//e->SetSource(mItemType);
			//EventManager::SendEvent(e);

			this->ShowWindow(SW_SHOW);
		}

		void EditItemPanel::OnDeactivate()
		{
			this->ShowWindow(SW_HIDE);
			this->ClearCtrl();
			PropertiesDlg::Hide();
			EventManager::DetachLogicEventHandler(this);
			EventManager::DetachUiEventHandler(this);
		}

		void EditItemPanel::Layout()
		{
			mConfig = new ut::Config(_T("layout/EditItemPanel.ini"));
			//this->Layout(this, _T("EditItemPanel"));
			LAYOUT(IDC_CHINESS_STATIC);
			LAYOUT(IDC_CHINESS_EDIT);
			LAYOUT(IDC_JAPANESS_STATIC);
			LAYOUT(IDC_JAPANESS_EDIT);
			LAYOUT(IDC_BUY_STATIC);
			LAYOUT(IDC_BUY_EDIT);
			LAYOUT(IDC_SELL_STATIC);
			LAYOUT(IDC_SELL_EDIT);
			LAYOUT(IDC_CATEGORY_STATIC);
			LAYOUT(IDC_CATEGORY_COMBO);
			LAYOUT(IDC_PROPERTY_STATIC);
			delete mConfig;

			this->UpdateWindow();
		}

		inline void EditItemPanel::Layout(CWnd* wnd, const ut::Char* section)
		{
			int left = mConfig->GetInt(section, _T("left"));
			int top = mConfig->GetInt(section, _T("top"));
			int width = mConfig->GetInt(section, _T("width"));
			int height = mConfig->GetInt(section, _T("height"));
			UINT flag = SWP_NOZORDER;
			if (!mConfig->GetBool(section, _T("sizable"), false))
			{
				flag |= SWP_NOSIZE;
			}
			wnd->SetWindowPos(0, left, top, width, height, flag);
			wnd->UpdateWindow();
		}

		inline void EditItemPanel::LayoutItem(UINT id, const ut::Char* section)
		{
			CWnd* item = this->GetDlgItem(id);
			this->Layout(item, section);
		}

		inline void EditItemPanel::MoveCtrl(int index, CWnd* wnd)
		{
			int y = CTRL_BASE_Y + index * CTRL_HEIGHT;
			wnd->SetWindowPos(0, 0, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
		}

		inline void EditItemPanel::MoveCtrl()
		{
			for (int i = 0; i < mCtrls.size(); ++i)
			{
				this->MoveCtrl(i, mCtrls[i]);
			}
		}

		inline void EditItemPanel::ClearCtrl()
		{
			for (std::vector<PropertyCtrl*>::iterator itr = mCtrls.begin();
				itr != mCtrls.end(); ++itr)
			{
				PropertyCtrl* ctrl = *itr;
				ctrl->DestroyWindow();
				delete ctrl;
			}
			mCtrls.erase(mCtrls.begin(), mCtrls.end());
		}

		void EditItemPanel::DeleteProperty(PropertyCtrl* ctrl)
		{
			mItem->DelProprety(ctrl->GetProperty());
			ctrl->DestroyWindow();
			delete ctrl;
			for (std::vector<PropertyCtrl*>::iterator itr = mCtrls.begin();
				itr != mCtrls.end(); ++itr)
			{
				mCtrls.erase(itr);
				break;
			}
			this->MoveCtrl();
		}

		void EditItemPanel::SetItemType(int itemType)
		{
			if (mItem)
			{
				mItem->SetItemType(itemType);
			}

			ut::Event* evn = ut::Event::NewEvent(ut::EventType::UI, UEC::RequestItemCategories);
			evn->SetSource(itemType);
			EventManager::SendEvent(evn);

			ut::Event* e = ut::Event::NewEvent(ut::EventType::UI, UEC::RequestPropertyTemplates);
			e->SetSource(itemType);
			EventManager::SendEvent(e);
		}

		void EditItemPanel::SetItem(Item* item)
		{
			mItem = item;
			int itemType = mItem->GetItemType();
			if (itemType)
			{
				this->SetItemType(itemType);
			}

			this->SetDlgItemText(IDC_CHINESS_EDIT, item->GetChinessName().c_str());
			this->SetDlgItemText(IDC_JAPANESS_EDIT, item->GetJapanessName().c_str());
			CString text;
			text.Format(_T("%d"), item->GetBuyPrice());
			this->SetDlgItemText(IDC_BUY_EDIT, text);
			text.Format(_T("%d"), item->GetSellPrice());
			this->SetDlgItemText(IDC_SELL_EDIT, text);
			this->ClearCtrl();

			const Properties& ps = item->GetProperties();
			for (Properties::const_iterator itr = ps.begin(); itr != ps.end(); ++itr)
			{
				this->AddCtrl(*itr);
			}
		}

		Item* EditItemPanel::GetItem() const
		{
			CString text;
			this->GetDlgItemText(IDC_CHINESS_EDIT, text);
			mItem->SetChinessName(text.GetBuffer());
			this->GetDlgItemText(IDC_JAPANESS_EDIT, text);
			mItem->SetJapanessName(text.GetBuffer());
			int i = this->GetDlgItemInt(IDC_BUY_EDIT, 0);
			mItem->SetBuyPrice(i);
			i = this->GetDlgItemInt(IDC_SELL_EDIT, 0);
			mItem->SetSellPrice(i);

			return mItem;
		}

		void EditItemPanel::AddCtrl(Property* p)
		{
			PropertyCtrl* ctrl = new PropertyCtrl(this, p);
			ctrl->Create(CTRL_HEIGHT, this);
			int index = mCtrls.size();
			mCtrls.push_back(ctrl);
			this->MoveCtrl(index, ctrl);
		}
	}
}

